
<template>
  <el-dialog :title="showDialogTitle" :visible="showDialog" @close="onCancelBtn">
    <el-form ref="refForm" :model="formData" :rules="rules">
      <el-form-item label="部门名称" label-width="120px" prop="name">
        <el-input v-model.trim="formData.name" autocomplete="off" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门编码" label-width="120px" prop="code">
        <el-input v-model.trim="formData.code" autocomplete="off" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门负责人" label-width="120px" prop="manager">
        <el-select v-model="formData.manager" placeholder="请选择" @focus="loadEmployeeSimpleInfo">
          <el-option
            v-for="item in options"
            :key="item.id"
            :label="item.username"
            :value="item.username"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="部门介绍" label-width="120px" prop="introduce">
        <el-input v-model.trim="formData.introduce" autocomplete="off" type="textarea" placeholder="1-300个字符" />
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="onCancelBtn">取 消</el-button>
      <el-button type="primary" @click="onSureBtn">确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
// 导入获取最新的部门架构信息的接口函数
import { getDepartments, addDepartments, getDepartmentsDetails, editDepartmentsDetails } from '@/api/departments.js';
// 导入获取员工简单信息列表的方法
import { getEmployeeSimpleInfo } from '@/api/employee.js';
export default {
  props: {
    showDialog: {
      type: Boolean,
      default: false,
    },
    // 获取树形结构的节点数据
    treeData: {
      required: true,
      type: Object,
    },
  },
  data() {
    // 检查部门名称是否重复
    // value 是用户输入的添加为子部门的名字
    const checkRepeatName = async(rule, value, callback) => {
      // 首先获取最新的部门信息
      const { depts } = await getDepartments();
      // 根据这个最新的数据信息来查找当前部门的子部门名字有没有跟要添加的子部门的名字相同的
      // this.treeData.id是用户当前点击的节点的id 只有当item.id === this.treeData.id 的时候才能说明这个item是
      // 当前点击的节点的子节点
      let isRepeated = false;
      if (this.formData.id) {
        // 有id 证明是编辑业务
        // 编辑业务的名字校验规则，就是跟当前的点击的同级部门里面不可以有同名字的
        // 根据this.treeData.pid 去数剧里面找，首先要找到所有的同级部门的数据，并且找到的同级部门的数据还不能包括自己这一条数据本身，然后在去找名字相同的同级部门数据
        isRepeated = depts.filter(item => item.pid === this.treeData.pid && item.id !== this.treeData.id).some(item => item.name === value);
      } else {
        isRepeated = depts.filter(item => item.pid === this.treeData.id).some(item => item.name === value);
      }
      isRepeated ? callback(new Error(`在同级部门下面已经有${value}这个部门名称了`)) : callback();
    };
    // 检查部门编码是否重复
    // 这里的value就是用户当前输入的部门编码
    const checkRepeatCode = async(rule, value, callback) => {
      const { depts } = await getDepartments();
      let isRepeated = false;
      if (this.formData.id) {
        // 编辑业务;
        isRepeated = depts.some(item => item.code !== this.formData.code && item.code === value && value);
      }
      isRepeated = depts.some(item => item.code === value && value); // 这里要保证value不能为空
      isRepeated ? callback(new Error(`组织架构中已经有${value}这个部门编码了`)) : callback();
    };
    return {
      // form表单校验数据
      formData: {
        name: '',
        code: '',
        manager: '',
        introduce: '',
      },
      // form表单的校验规则
      rules: {
        name: [{ required: true, message: '部门名称不能为空', trigger: 'blur' },
          { min: 1, max: 50, message: '部门名称要求1-50个字符', trigger: 'blur' },
          { validator: checkRepeatName, trigger: 'blur' }],
        code: [{ required: true, message: '部门编码不能为空', trigger: 'blur' },
          { min: 1, max: 50, message: '部门编码要求1-50个字符', trigger: 'blur' },
          { validator: checkRepeatCode, trigger: 'blur' }],
        manager: [{ required: true, message: '部门负责人不能为空', trigger: 'blur' },
        ],
        introduce: [{ required: true, message: '部门介绍不能为空', trigger: 'blur' },
          { min: 1, max: 300, message: '部门介绍要求1-300个字符', trigger: 'blur' }],
      },
      // select的数据源
      options: [],
      // select的默认显示值
      // value: '',
    };
  },
  computed: {
    showDialogTitle() {
      return this.formData.id ? '编辑部门' : '新增子部门';
    },
  },
  methods: {
    // 加载员工简单列表
    async loadEmployeeSimpleInfo() {
      const res = await getEmployeeSimpleInfo();
      // console.log(res);
      this.options = res;
    },
    // 点击对话框确定按钮的事件
    onSureBtn() {
      // 手动对表单进行校验
      this.$refs.refForm.validate(async valid => {
        if (valid) {
          if (this.formData.id) {
            // 如果有id就是编辑逻辑
            await editDepartmentsDetails(this.formData);
          } else {
            // 证明表单手动校验通过
            // 发起更新部门信息的请求
            await addDepartments({ ...this.formData, pid: this.treeData.id });
          }
          // 通知父组件更新部门列表
          this.$emit('updateDeparts');
          // 通知父组件关闭对话框
          // this.$emit('update:showDialog', false);
          this.$emit('cancelDialog');
        }
      });
    },
    // 点击对话框取消按钮的事件
    onCancelBtn() {
      // 为了防止用户点完编辑之后，formData在点新增子部门的时候，formData里面的id并没有被删除，因此在这里重新手动清除一下数据，form表单里面的重置表单事件，只能重置在data里面预先定义好的数据。
      this.formData = {
        name: '',
        code: '',
        manager: '',
        introduce: '',
      };
      // 拿到当前组件的实例，重置表单
      this.$refs.refForm.resetFields();
      // 关闭对话框
      this.$emit('update:showDialog', false);
    },
    // 根据id获取编辑部门详细信息
    async loadEditDepartmentsDetails(id) {
      // 注意：这里不要用this.treeData.id 因为props接受父组件传过来的值是异步的，有可能loadEditDepartmentsDetails方法被调用的时候，值还么有传给子组件
      // 父组件调用子组件的方法，先是设置了data数据，直接调用方法，因此我们采用引用ref的方式来调用子组件的方法，并且给在父组件调用方法的时候，将id传过来
      // await getDepartmentsDetails(this.treeData.id);
      const res = await getDepartmentsDetails(id);
      this.formData = res;
    },
  },
};
</script>

<style scoped>

</style>
